
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;

namespace Swaf.Container
{
    /// <summary>
    /// Summary description for NameAddressStack.
    /// </summary>
    [Serializable]
    public class NameAddressStack : INameAddressSupport
    {
        protected IList m_stack = new ArrayList();
        public NameAddressStack(params INameAddressSupport[] ns)
        {
			foreach(INameAddressSupport n in ns)
				if(n != null)
					m_stack.Add(n);
        }

        public NameAddressStack push(INameAddressSupport el)
        {
            m_stack.Add(el);
            return this;
        }

        public void pop()
        {
            m_stack.RemoveAt(m_stack.Count - 1);
        }
        #region INameAddressSupport Members

        public bool containsField(string nameAddress)
        {
            for (int x = m_stack.Count - 1; x >= 0; --x)
            {
                if (((INameAddressSupport)m_stack[x]).containsField(nameAddress))
                    return true;
            }
            return false;
        }

        public bool isGetOnly
        {
            get
            {
                if (m_stack.Count > 0)
                    return ((INameAddressSupport)m_stack[m_stack.Count - 1]).isGetOnly;
                return true;
            }
        }

        public Swaf.Container.XmlSerializationSupport SerializationSupport
        {
            get
            {
                // TODO:  Add NameAddressStack.SerializationSupport getter implementation
                return new Swaf.Container.XmlSerializationSupport();
            }
        }

        public void put(string nameAddress, object val, object extraInfo)
        {
            Exception currException = null;

            for (int i = m_stack.Count - 1; i >= 0; --i)
            {
                try
                {
                    ((INameAddressSupport)m_stack[m_stack.Count - 1]).put(nameAddress, val, extraInfo);

                    // Put attempt worked so break out of the loop
                    currException = null;
                    break;
                }
                catch (Exception e)
                {
                    currException = e;
                }
            }

            // If it never could be put in any of the INameAddressSupport impls, throw exception
            if (currException != null)
            {
                throw new BaseException(string.Format("Unable to 'put' in NameAddressStack.  Key: {0}", nameAddress), currException);
            }
        }

        void Swaf.Container.INameAddressSupport.put(string nameAddress, object val)
        {
            Exception currException = null;

            for (int i = m_stack.Count - 1; i >= 0; --i)
            {
                try
                {
                    ((INameAddressSupport)m_stack[i]).put(nameAddress, val);

                    // Put attempt worked so break out of the loop
                    currException = null;
                    break;
                }
                catch (Exception e)
                {
                    currException = e;
                }
            }

            // If it never could be put in any of the INameAddressSupport impls, throw exception
            if (currException != null)
            {
                throw new BaseException(string.Format("Unable to 'put' in NameAddressStack.  Key: {0}", nameAddress), currException);
            }
        }

        public string getXml(string options)
        {
            // TODO:  Add NameAddressStack.getXml implementation
            return null;
        }

        public object get(string nameAddress)
        {
            for (int x = m_stack.Count - 1; x >= 0; --x)
            {
                if (((INameAddressSupport)m_stack[x]).containsField(nameAddress))
                    return ((INameAddressSupport)m_stack[x]).get(nameAddress);
            }
            return null;
        }

        object Swaf.Container.INameAddressSupport.get(string nameAddress, object oneArg)
        {
            for (int x = m_stack.Count - 1; x >= 0; --x)
            {
                if (((INameAddressSupport)m_stack[x]).containsField(nameAddress))
                    return ((INameAddressSupport)m_stack[x]).get(nameAddress, oneArg);
            }
            return null;
        }

        object Swaf.Container.INameAddressSupport.get(string nameAddress, params object[] infoArgs)
        {
            for (int x = m_stack.Count - 1; x >= 0; --x)
            {
                if (((INameAddressSupport)m_stack[x]).containsField(nameAddress))
                    return ((INameAddressSupport)m_stack[x]).get(nameAddress, infoArgs);
            }
            return null;
        }

        public string Xml
        {
            get
            {
                // TODO:  Add NameAddressStack.Xml getter implementation
                return null;
            }
        }

        #endregion
		public IEnumerator GetEnumerator() { return ((IEnumerable)m_stack[0]).GetEnumerator(); }
	}
}
